<h1 id="please-basics" class="title-1">Please basics</h1>

<p>
  If you're familiar with Blaze / Bazel, Buck or Pants you will probably find
  Please very familiar. Otherwise, don't worry, it's not very complicated...
</p>

<section class="mt4">
  <h2 id="build-files" class="title-2">BUILD files</h2>

  <p>
    Please targets are defined in files named BUILD. These are analogous to
    Makefiles in that they define buildable targets for that directory.
    Fortunately, they do so in a rather nicer syntax.<br />
    We refer to a directory containing a BUILD file as a <em>package</em>.
  </p>

  <p>
    For more information on the format of BUILD files, read the
    <a class="copy-link" href="/language.html">language specification</a>
    here.
  </p>
</section>

<section class="mt4">
  <h2 class="title-2" id="build-targets">Build targets</h2>

  <p>
    Each BUILD file can contain a number of <em>build targets</em>. These targets are the tasks that the build system
    can perform. They are described using "build rules" which are in turn defined in plugins for each language. These
    must be added to your project before you can use them. To get started, run
    <code class="code">plz init plugin [python|java|go|cc]</code>. This will make build rules for that language
    available to you in your BUILD files. An example is probably worth 1000 words at this point:
  </p>

  <div data-widget="tabs">
    <div class="flex">
      <ul class="tabs__tablist" role="tablist">
        <li
          id="python-targets-tab"
          class="tabs__tab tabs__tab--selected"
          data-tab="py"
          role="tab"
          aria-controls="python-targets-panel"
          tabindex="0"
        >
          Python
        </li>
        <li
          id="java-targets-tab"
          class="tabs__tab"
          data-tab="java"
          role="tab"
          aria-controls="java-targets-panel"
          tabindex="0"
        >
          Java
        </li>
        <li
          id="go-targets-tab"
          class="tabs__tab"
          data-tab="go"
          role="tab"
          aria-controls="go-targets-panel"
          tabindex="0"
        >
          Go
        </li>
        <li
          id="c-targets-tab"
          class="tabs__tab"
          data-tab="c"
          role="tab"
          aria-controls="c-targets-panel"
          tabindex="0"
        >
          C
        </li>
        <li
          id="cpp-targets-tab"
          class="tabs__tab"
          data-tab="cpp"
          role="tab"
          aria-controls="cpp-targets-panel"
          tabindex="0"
        >
          C++
        </li>
      </ul>
    </div>

    <div class="tabs__panels">
      <pre
        id="python-targets-panel"
        class="f7 tabs__panel tabs__panel--selected"
        data-panel="py"
        role="tabpanel"
        aria-labelledby="python-targets-tab"
      >
        <!-- prettier-ignore -->
        <code data-lang="plz">
    python_library(
        name = 'my_library',
        srcs = ['file1.py', 'file2.py'],
    )

    python_binary(
        name = 'my_binary',
        main = 'my_main.py',
        deps = [':my_library'],
    )

    python_test(
        name = 'my_library_test',
        srcs = ['my_library_test.py'],
        deps = [':my_library'],
    )
        </code>
      </pre>

      <pre
        id="java-targets-panel"
        class="f7 tabs__panel"
        data-panel="java"
        role="tabpanel"
        aria-labelledby="java-targets-tab"
      >
        <!-- prettier-ignore -->
        <code data-lang="plz">
    java_library(
        name = 'my_library',
        srcs = ['File1.java', 'File2.java'],
    )

    java_binary(
        name = 'my_binary',
        main_class = 'com.example.Main',
        deps = [':my_library'],
    )

    java_test(
        name = 'my_library_test',
        srcs = ['MyLibraryTest.java'],
        deps = [':my_library'],
    )
        </code>
      </pre>

      <pre
        id="go-targets-panel"
        class="f7 tabs__panel"
        data-panel="go"
        role="tabpanel"
        aria-labelledby="go-targets-tab"
      >
        <!-- prettier-ignore -->
        <code data-lang="plz">
    go_library(
        name = 'my_library',
        srcs = ['file1.go', 'file2.go'],
    )

    go_binary(
        name = 'my_binary',
        srcs = ['main.go'],
        deps = [':my_library'],
    )

    go_test(
        name = 'my_library_test',
        srcs = ['my_library_test.go'],
        deps = [':my_library'],
    )
        </code>
      </pre>

      <pre
        id="c-targets-panel"
        class="f7 tabs__panel"
        data-panel="c"
        role="tabpanel"
        aria-labelledby="c-targets-tab"
      >
        <!-- prettier-ignore -->
        <code data-lang="plz">
    c_library(
        name = 'my_library',
        srcs = ['file1.c', 'file2.c'],
        hdrs = ['file1.h'],
    )

    c_binary(
        name = 'my_binary',
        srcs = ['main.c'],
        deps = [':my_library'],
    )

    c_test(
        name = 'my_library_test',
        srcs = ['my_library_test.c'],
        deps = [':my_library'],
    )
        </code>
      </pre>

      <pre
        id="cpp-targets-panel"
        class="f7 tabs__panel"
        data-panel="cpp"
        role="tabpanel"
        aria-labelledby="cpp-targets-tab"
      >
        <!-- prettier-ignore -->
        <code data-lang="plz">
    cc_library(
        name = 'my_library',
        srcs = ['file1.cpp', 'file2.cpp'],
        hdrs = ['file1.hpp'],
    )

    cc_binary(
        name = 'my_binary',
        srcs = ['main.cpp'],
        deps = [':my_library'],
    )

    cc_test(
        name = 'my_library_test',
        srcs = ['my_library_test.cpp'],
        deps = [':my_library'],
    )
        </code>
      </pre>
    </div>
  </div>
  <p>
    The code above defines 3 targets: a library called <code class="code">my_library</code>, a binary called
    <code class="code">my_binary</code>, and a test target called <code class="code">my_library_test</code>. There are some
    differences between languages but this is the typical pattern that Please build rules follow:
  </p>
  <ul class="bulleted-list">
    <li>
      <span>
        The <code class="code">my_library</code> rules build first party packages, modules, or translation units,
        depending on the nomenclature of the language. These are then made available to other rules within the project.
      </span>
    </li>
    <li>
      <span>
        The <code class="code">my_binary</code> rules create a runnable "binary target" that depends on
        <code class="code">my_library</code>. These must have some kind of entry point, e.g.
        <code class="code">python_binary</code> requires that a python file be passed via
        <code class="code">main</code>, however other languages may require a source file with a main method or similar. The binary targets
        can be run via <code class="code">plz run</code>.
      </span>
    </li>
    <li>
      <span>
        The <code class="code">my_library_test</code> defines a test on
        <code class="code">my_library</code>. Tests can be run via <code class="code">plz test</code> or
        <code class="code">plz cover</code>, and their results are aggregated.
      </span>
    </li>
  </ul>

  <p>
    This illustrates the core points of Please; every rule clearly defines its
    inputs - its own sources and its dependencies - and since these are known
    Please can be aggressive about parallelism, caching and reusing build
    artifacts.
  </p>
</section>

<section class="mt4">
  <h2 id="how-to-use-targets" class="title-2">Okay, great, so how do I actually use them?</h2>

  <p>
    Let's assume the build rules given above are defined in a file in your repo
    named <code class="code">package/BUILD</code>. You can do the following:
  </p>

  <ul class="bulleted-list">
    <li>
      <span>
        <code class="code">plz build //package:my_library</code> builds the
        library. This isn't drastically useful on its own, of course...
      </span>
    </li>
    <li>
      <span>
        <code class="code">plz build //package:my_binary</code> builds the
        binary and all needed libraries that it depends on. That produces a
        single output file which you could copy to another machine.
      </span>
    </li>
    <li>
      <span>
        <code class="code">plz run //package:my_binary</code> builds and runs
        the binary immediately.
      </span>
    </li>
    <li>
      <span>
        <code class="code">plz test //package:my_library_test</code> builds and
        runs the test and shows you the results.</span
      >
    </li>
  </ul>
</section>

<section class="mt4">
  <h2 class="title-2" id="labels">Build labels</h2>

  <p>
    Above, we have been referring to each target via its <em>build labels</em>. As you've just seen,
    these are of the form <code class="code">//package:target</code>, where
    <code class="code">package</code> is the path from the repo root to that
    package, and <code class="code">target</code> is the name of the target
    within that package.
</p>
<p>
    This is the most common form to identify targets absolutely, however you may see build labels
    of the form <code class="code">:my_library</code>. These are local build labels that refer to a
    target in the current BUILD file.
  </p>

  <p>
    The convention is to use
    <code class="code">lower_case_with_underscores</code> for both package names
    and target names.<br />
    This is not just for looks; in many languages (eg. Python) the file path
    appears within the source files, and so it's important to choose something
    that's a valid lexical identifier.
  </p>

  <p>There are also some special pseudo-labels:</p>

  <ul class="bulleted-list">
    <li>
      <span>
        <code class="code">//mypackage:all</code> refers to all targets in
        'mypackage'.</span
      >
    </li>
    <li>
      <span>
        <code class="code">//mypackage/...</code> refers to all targets in
        'mypackage' and anywhere beneath it in the filesystem.</span
      >
    </li>
  </ul>

  <p>
    Build targets can't use these as dependencies; these are primarily for using
    on the command line or in the visibility specification for a target.
    The special pseudo-label <code class="code">PUBLIC</code> is equivalent to
    <code class="code">//...</code> in visibility specifications.
  </p>
</section>

<section class="mt4">
  <h2 id="file-format" class="title-2">The BUILD file format</h2>

  <p>
    You may have noticed that the invocations in BUILD files look a bit like
    function calls. This is not coincidence; it is not just a declarative
    language, it's also a scripting language that allows you to programmatically
    create targets. For example, let's say you want to translate your
    documentation to a bunch of languages:
  </p>

  <pre class="code-container">
    <!-- prettier-ignore -->
    <code data-lang="plz">
    for language in ['en_NZ', 'en_GB', 'it_IT', 'es_MX', 'el_GR']:
        lang_docs = genrule(
            name = 'txt_documentation_' + language,
            srcs = ['docs.txt'],
            outs = [f'docs_{language}.txt'],
            tools = ['//tools:translate_tool'],
            cmd = f'$TOOL -i $SRC --language {language} &gt; "$OUT"',
        )

        genrule(
            name = 'documentation_' + language,
            srcs = [lang_docs],
            outs = [f'docs_{language}.html'],
            tools = ['//tools:html_doc_tool'],
            cmd = '$TOOL --src $SRC --out "$OUT"',
            visibility = ['PUBLIC'],
        )
    </code>
  </pre>

  <p>
    Obviously this would be a bit repetitive if you redefined the rules
    separately for each language. Instead, we can take advantage of the build
    language to genericise them across languages; for each language we translate
    it and then format it as HTML.
  </p>

  <p>
    The language itself shares some similarity to Python so it should feel
    familiar to many people. There is a
    <a class="copy-link" href="/language.html">complete description</a>
    of it available if you're curious about more details.
  </p>
</section>

<div class="pagination">
  <div class="pagination__previous">
    <a class="copy-link" href="/codelabs.html">Codelabs</a>
  </div>
  <div class="pagination__next">
    <a class="copy-link" href="/dependencies.html">Third-party dependencies</a>
  </div>
</div>
